//-----------------------------------------------------------------------------
// Comm_UART.c
//-----------------------------------------------------------------------------
// Copyright (C) 2010 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// [*** TEMPLATE INFORMATION ***]
// Filename: Fnnn_Comm_CommType.c
// nnn => Fill-in with the MCU family part number.
// CommType => Fill-in Comm interface name.
// Examples: Comm_SMB.c, Comm_UART.c
//
//
//
//
// Target:         C8051Fxxx (Any Silicon Labs Flash MCU)
// Tool chain:     Generic
// Command Line:   None
//
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "TargetBL_Config.h"
#include "TargetBL_Interface.h"

#include "UART_Interface.h"
#include "CRC.h"
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

extern U8 xdata rx_buf[TGT_BL_BUF_SIZE];
extern U8 data rx_len;
extern U8 data server_address;
extern U16 data uart_timestamp;
extern bit user_app_ready;
//-----------------------------------------------------------------------------
// Function Prototypes (Local)
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//  uart send, count max number is 255, limited by XRAM size
void uart_send(U8 *buf, U8 count)
{
    U8 *ptr = buf;
    do{
        SBUF0 = *ptr++;
        while(TI0 == 0);
        TI0 = 0;
    }while(--count);
}

// uart receive
void uart_receive()
{
    while(1)
    {
        rx_len = 0;

        do{
            while(RI0)
            {
                RI0 = 0;
                rx_buf[rx_len++ & TGT_BL_BUF_SIZE_MASK] = SBUF0;
                uart_timestamp = SystemTick();
            }
            SCON0 &= ~0x80; // CLEAR OVR0
        }while(SystemTick() - uart_timestamp < ONE_MS);

        if (user_app_ready && Timeouts())
            RSTSRC = 0x12; // Initiate software reset with vdd monitor enabled
    
        ResetTimeouts();
        
        if (rx_len < 4)
            continue;

        if (Get_Buf_CRC(rx_buf, rx_len-2) != *(U16*)&rx_buf[rx_len-2])
            continue;

        if (rx_buf[0] == server_address || rx_buf[0] == 0)
            return;
    }
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
